package com.gitee.deament.server.core.cli.db.list;

import cn.hutool.core.util.NumberUtil;
import com.gitee.deament.server.config.SystemConfig;
import com.gitee.deament.server.core.annotation.CliHander;
import com.gitee.deament.server.core.cli.AbstractCli;
import com.gitee.deament.server.core.data.ConnectData;
import com.gitee.deament.server.core.data.DBData;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.List;

/**
 * LSET key index value
 * 可用版本： >= 1.0.0
 * 时间复杂度：对头元素或尾元素进行 LSET 操作，复杂度为 O(1)。其他情况下，为 O(N)， N 为列表的长度。
 * 将列表 key 下标为 index 的元素的值设置为 value 。
 *
 * 当 index 参数超出范围，或对一个空列表( key 不存在)进行 LSET 时，返回一个错误。
 *
 * 关于列表下标的更多信息，请参考 LINDEX key index 命令。
 *
 * 返回值
 * 操作成功返回 ok ，否则返回错误信息。
 * @author  deament
 */
@CliHander(command = "LSET")
public class LSETcli extends AbstractCli {
    @Override
    public void executeCli(ChannelHandlerContext channelHandlerContext, String command) {
        List<String> cliValues = getValues(command);
        if (cliValues.size() != 4) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR wrong number of arguments for 'LSET' command"));
            return;
        }
        int db = ConnectData.SELECT_DB_STORAGE.getUseDB(channelHandlerContext.channel().id().asLongText());
        DBData dbData = SystemConfig.dbData;
        String key = cliValues.get(1);
        String index = cliValues.get(2);
        String valueStr = cliValues.get(3);
        if(!NumberUtil.isInteger(index)||Integer.parseInt(index)<0){
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("第三个参数错误"));
            return ;
        }
        try {
            List<String> value = SystemConfig.dbData.getList(db, key).getValue();
            if(Integer.parseInt(index)>value.size()){
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR index out of range"));
                return ;
            }
            value.set(Integer.parseInt(index), valueStr);
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ok"));
        } catch (Exception e) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(e.getMessage()));
        }
    }
}
